package com.zmn.oms.third.daowei.service.impl;

import com.alibaba.fastjson.JSON;
import com.zmn.cds.httpcall.CdsHttpCallClient;
import com.zmn.cds.httpcall.CdsHttpCallResult;
import com.zmn.cds.httpcall.biz.orderclue.QueryOrderClueDIO;
import com.zmn.cds.httpcall.biz.orderclue.QueryOrderClueDRO;
import com.zmn.common.constant.GlobalConsts;
import com.zmn.common.constant.StatusConsts;
import com.zmn.common.utils.date.DateUtil;
import com.zmn.common.utils.math.MoneyUtil;
import com.zmn.common.utils.number.NumberUtil;
import com.zmn.oms.business.interfaces.log.OrderLogBService;
import com.zmn.oms.business.interfaces.notifylog.OrderNotifyLogBService;
import com.zmn.oms.business.interfaces.remark.OrderRemarkBService;
import com.zmn.oms.common.constant.CdsConsts;
import com.zmn.oms.common.constant.OrderConsts;
import com.zmn.oms.common.constant.OrderLogConsts;
import com.zmn.oms.common.constant.OrderStatusConsts;
import com.zmn.oms.common.dto.ResultDTO;
import com.zmn.oms.common.enums.ChannelFacade;
import com.zmn.oms.common.exception.OmsBaseException;
import com.zmn.oms.model.entity.notifylog.OrderNotifyLog;
import com.zmn.oms.model.entity.order.OrderExtend;
import com.zmn.oms.model.entity.work.OrderWork;
import com.zmn.oms.model.entity.work.OrderWorkLogChange;
import com.zmn.oms.model.vo.remark.OrderRemarkDetailVO;
import com.zmn.oms.model.vo.remark.OrderRemarkVO;
import com.zmn.oms.services.interfaces.order.OrderExtendService;
import com.zmn.oms.services.interfaces.work.OrderWorkService;
import com.zmn.oms.third.core.tracker.FacadeTracker;
import com.zmn.oms.third.daowei.DaoweiApiInvoker;
import com.zmn.oms.third.daowei.DaoweiConsts;
import com.zmn.oms.third.daowei.dto.BaseRsp;
import com.zmn.oms.third.tc58.Tc58Consts;
import com.zmn.oms.zmn.business.interfaces.open.OrderChangeNotifyService;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.LinkedList;
import java.util.List;
import java.util.Objects;
import java.util.Optional;

/**
 * @author: huangyifeng
 * @description: 向到位推送订单变化通知的服务
 * @create: 2020-02-27 16:33
 **/
@Slf4j
@Service("daoweiNotifyService")
public class DaoweiNotifyServiceImpl implements OrderChangeNotifyService {

    @Autowired
    private OrderWorkService orderWorkService;
    @Autowired
    private OrderLogBService orderLogBService;
    @Autowired
    private OrderRemarkBService orderRemarkBService;
    @Resource
    private OrderNotifyLogBService orderNotifyLogBService;
    @Autowired
    private OrderExtendService orderExtendService;

    @Override
    @SuppressWarnings("all")
    public void notifyChange(OrderWorkLogChange orderWorkLogChange) throws OmsBaseException {
        int logType = orderWorkLogChange.getLogType().intValue();

        if (StringUtils.isBlank(orderWorkLogChange.getOuterId())) {
            return;
        }

        // 查询该订单是否在CDS中存在，开始
        OrderExtend dbOrderExtend = orderExtendService.findMiniOrderExtendByOrderId(orderWorkLogChange.getWorkId());
        if (NumberUtil.isNotNullOrZero(dbOrderExtend.getClueId())) {
            log.info(
                    "【到位】CDS录入订单，由CDS负责接单，orderWorkLogChange=[{}]",
                    com.github.ltsopensource.core.json.JSON.toJSONString(orderWorkLogChange)
            );
            return;
        }

        // 查询该订单是否在CDS中存在，结束


        boolean needSync = false;
        FacadeTracker.FacadeTrackerCore tracker = FacadeTracker.getTracker()
                .dataOut(ChannelFacade.DAOWEI)
                .orderId(orderWorkLogChange.getOrderId());
        try {
            // 渠道备注
            if (OrderLogConsts.ORDER_LOG_TYPE_CHANNEL_REMARK == logType) {
                // 渠道申请退款
                if ("applyRefund".equals(orderWorkLogChange.getExtData())) {
                    needSync = true;
                    tracker.remark("回复退款结果");
                    syncRefund(orderWorkLogChange);
                }
            }
            // 预付款之后会自动确认（派单）
            // 直选订单（抢单模式）不需要推送确认状态
            else if (OrderLogConsts.ORDER_LOG_TYPE_DISTRIBUTE == logType
                    && !Objects.equals(DaoweiConsts.CHANNEL_ID_ZX, orderWorkLogChange.getChannelId())) {
                needSync = true;
                tracker.remark("回复确认接单");
                syncConfirmReceipt(orderWorkLogChange);
            }
            // 修改预约时间
            else if (isChangeDutyTime(logType, orderWorkLogChange)) {
                needSync = true;
                tracker.remark("同步预约时间");
                syncDutyTime(orderWorkLogChange);
            }
            // 师傅报价（同步到位补差价金额）
            else if (isNeedSyncPriceDifference(logType)) {
                needSync = true;
                tracker.remark("同步补差价金额");
                syncPriceDifference(orderWorkLogChange);
            }
            // 完成(平台代收金额)
            else if (OrderLogConsts.ORDER_LOG_TYPE_COMPLETE == logType) {
                needSync = true;
                // 同步啄木鸟收款额（如果有）
                if (syncMasterAmount(orderWorkLogChange)) {
                    tracker.remark("同步师傅收款额")
                            .commit();
                }

                // 同步订单完成
                tracker = FacadeTracker.getTracker()
                        .dataOut(ChannelFacade.DAOWEI)
                        .orderId(orderWorkLogChange.getOrderId())
                        .remark("同步订单完成");
                syncOrderComplete(orderWorkLogChange);
            }
            // 取消、失败、弃单
            else if (OrderLogConsts.ORDER_LOG_TYPE_CANCEL == logType || OrderConsts.ORDER_OP_TYPE_FAIL == logType
                    || OrderConsts.ORDER_OP_TYPE_DISCARD == logType) {
                needSync = true;
                tracker.remark("同步平台取消订单");
                syncOrderCancel(orderWorkLogChange);
            }
        } catch (Exception e) {
            tracker.error(e, null);
        }

        if (needSync) {
            tracker.commit();
        }
        else {
            tracker.discard();
        }
    }

    /**
     *
     * @return
     */
    private boolean isNeedSyncPriceDifference(int logType) {
        if (OrderLogConsts.ORDER_LOG_TYPE_MASTER_CHANGE_PRICE == logType    // 工程师填价格
                || OrderLogConsts.ORDER_LOG_TYPE_TAKE == logType    // 工程师领单
                || OrderLogConsts.ORDER_LOG_TYPE_SERVICEITEM == logType    // 更改服务项
                || OrderLogConsts.ORDER_LOG_TYPE_UPDATE_CHANNEL_PREPAY_AMOUNT == logType   // 改渠道预收
                || OrderConsts.ORDER_OP_TYPE_UPDATE_CHANNEL_PREPAY_AMOUNT == logType    // 改预付款
//                || OrderConsts.ORDER_OP_TYPE_ADMIN_UPDATE_CHANNEL_PREPAY_AMOUNT == logType  // 总部预付
                || OrderLogConsts.ORDER_LOG_TYPE_DISCOUNT_ARTIFICIAL_OPERATOR == logType   // 后台人工优惠
                || OrderLogConsts.ORDER_LOG_TYPE_DISCOUNT_ARTIFICIAL_MASTER == logType     // 工程师人工优惠
                || OrderConsts.ORDER_OP_TYPE_DISCOUNT_LEVEL_ONE == logType      // 优惠 六折
//                || OrderConsts.ORDER_OP_TYPE_DISCOUNT_LEVEL_TWO == logType      // 优惠 七折
//                || OrderConsts.ORDER_OP_TYPE_DISCOUNT_LEVEL_THREE == logType    // 优惠 九折
                ) {

            return true;
        }

        return false;
    }


    /**
     * 同步确认接单
     * @param orderWorkLogChange
     */
    private void syncConfirmReceipt(OrderWorkLogChange orderWorkLogChange) {
        Long orderId = orderWorkLogChange.getOrderId();
        OrderWork orderWork = orderWorkService.findOrderWorkByKey(orderId, orderId);

        BaseRsp result = DaoweiApiInvoker.pushOrderReceipt(orderWorkLogChange.getExtOuterData(), orderWork);

        log.info("【到位】同步确认接单：{}", JSON.toJSONString(orderWorkLogChange));

        // 商家接单
        _saveSyncResult(orderWorkLogChange, DaoweiConsts.SYNC_LOG_ONGOING, result);
    }

    /**
     * 同步预约时间
     * @param orderWorkLogChange
     */
    private void syncDutyTime(OrderWorkLogChange orderWorkLogChange) {
        Long orderId = orderWorkLogChange.getOrderId();
        OrderWork orderWork = orderWorkService.findOrderWorkByKey(orderId, orderId);

        BaseRsp result = DaoweiApiInvoker.pushDutyTime(orderWorkLogChange.getExtOuterData(), orderWork);

        log.info("【到位】同步预约时间：{}", JSON.toJSONString(orderWorkLogChange));

        _saveSyncResult(orderWorkLogChange, DaoweiConsts.SYNC_LOG_DUTY_TIME, result);
    }

    /**
     * 同步取消订单
     * @param orderWorkLogChange
     */
    private void syncOrderCancel(OrderWorkLogChange orderWorkLogChange) {
        Long orderId = orderWorkLogChange.getOrderId();
        OrderWork orderWork = orderWorkService.findOrderWorkByKey(orderId, orderId);


        OrderRemarkVO orderRemarkVO = orderRemarkBService.findOrderRemarkVO(
                orderId, orderId, OrderConsts.ORDER_REMARK_TYPE_CANCEL
        );
        // 刷单，同步完成
        if (isScalping(orderRemarkVO)) {
            BaseRsp result = DaoweiApiInvoker.pushOrderComplete(orderWorkLogChange.getExtOuterData(), orderWork);
            log.info("【到位】同步订单完成：{}", JSON.toJSONString(orderWorkLogChange));
            _saveSyncResult(orderWorkLogChange, DaoweiConsts.SYNC_LOG_COMPLETED, result);
        }
        // 正常取消
        else {
            // 取消备注（原因），需要将手写备注和选项备注进行拼接
            List<String> remarkList = new LinkedList<>();
            if (StringUtils.isNotBlank(orderRemarkVO.getContent())) {
                remarkList.add(orderRemarkVO.getContent());
            }
            if (orderRemarkVO.getDetailVOList() != null) {
                for (OrderRemarkDetailVO item : orderRemarkVO.getDetailVOList()) {
                    remarkList.add(item.getMapName());
                }
            }
            String remark = (remarkList.size() > 0) ? StringUtils.join(remarkList, "，") : null;

            // 平台取消订单
            BaseRsp result = DaoweiApiInvoker.pushOrderCancel(orderWorkLogChange.getExtOuterData(), orderWork, remark);

            log.info("【到位】同步平台取消订单：{}", JSON.toJSONString(orderWorkLogChange));

            _saveSyncResult(orderWorkLogChange, DaoweiConsts.SYNC_LOG_CANCELED, result);
        }
    }

    /**
     * 判断是不是刷单
     * @param orderRemarkVO
     * @return
     */
    private boolean isScalping(OrderRemarkVO orderRemarkVO) {
        if (orderRemarkVO == null || orderRemarkVO.getDetailVOList() == null) {
            return false;
        }

        Integer scalpId = DaoweiConsts.SCALP_ID;
        for (OrderRemarkDetailVO item : orderRemarkVO.getDetailVOList()) {
            if (Objects.equals(item.getMapId(), scalpId)) {
                return true;
            }
        }
        return false;
    }

    /**
     * 同步订单完成
     * @param orderWorkLogChange
     */
    private void syncOrderComplete(OrderWorkLogChange orderWorkLogChange) {
        Long orderId = orderWorkLogChange.getOrderId();
        OrderWork orderWork = orderWorkService.findOrderWorkByKey(orderId, orderId);

        // 完成
        BaseRsp result = DaoweiApiInvoker.pushOrderComplete(orderWorkLogChange.getExtOuterData(), orderWork);

        log.info("【到位】同步订单完成：{}", JSON.toJSONString(orderWorkLogChange));

        _saveSyncResult(orderWorkLogChange, DaoweiConsts.SYNC_LOG_COMPLETED, result);
    }

    /**
     * 同步退款解果
     * @param orderWorkLogChange
     */
    private void syncRefund(OrderWorkLogChange orderWorkLogChange) {
        Long orderId = orderWorkLogChange.getOrderId();
        OrderWork orderWork = orderWorkService.findOrderWorkByKey(orderId, orderId);
        OrderExtend orderExtend = orderExtendService.findMiniOrderExtendByOrderId(orderWork.getOrderId());

        // 订单已完成，同步拒绝退款
        if (orderWorkLogChange.getStatus() >= OrderStatusConsts.WORK_STATUS_COMPLETE) {
            BaseRsp result = DaoweiApiInvoker.pushRejectRefund(orderExtend.getExtOuterData(), orderWork, "订单已完成");
            log.info("【到位】同步拒绝退款：订单已完成. orderId=[{}]", orderId);
            _saveSyncResult(orderWorkLogChange, DaoweiConsts.SYNC_LOG_REJECT_REFUND, result);
        }
        // 同步同意退款
        else {
            BaseRsp result = DaoweiApiInvoker.pushApproveRefund(orderExtend.getExtOuterData(), orderWork);
            log.info("【到位】同步同意退款：orderId=[{}]", orderWork.getOrderId());
            _saveSyncResult(orderWorkLogChange, DaoweiConsts.SYNC_LOG_APPROVE_REFUND, result);
        }
    }

    /**
     * 同步需要补差价金额（用户需在到位平台补差价）
     * @param orderWorkLogChange
     */
    private void syncPriceDifference(OrderWorkLogChange orderWorkLogChange) {
        Long orderId = orderWorkLogChange.getOrderId();
        OrderWork orderWork = orderWorkService.findOrderWorkByKey(orderId, orderId);

        if (Objects.equals(GlobalConsts.SERV_CATEG_CLEAN, orderWork.getServCategId())) {
            // 清洗单，不需要同步
            return;
        }

        // 师傅收款额，即为需要补差价金额
        Integer money = Optional.ofNullable(orderWork.getMasterAmount()).orElse(0);

        if (money <= 0) {
            // 没有师傅收款额，不需要同步
            return;
        }

        BaseRsp result = DaoweiApiInvoker.pushPriceDifference(orderWorkLogChange.getExtOuterData(), orderWork,
                MoneyUtil.parseToYuan(money));

        log.info("【到位】同步需要补差价金额：{}", JSON.toJSONString(orderWorkLogChange));

        _saveSyncResult(orderWorkLogChange, DaoweiConsts.SYNC_LOG_SET_DIFF, result);
    }

    /**
     * 同步啄木鸟收款额（用户在商家平台补差价）    order_diff
     * @param orderWorkLogChange
     * @return
     */
    private boolean syncMasterAmount(OrderWorkLogChange orderWorkLogChange) {
        // 同步条件：已完成 & 非清洗单

        Long orderId = orderWorkLogChange.getOrderId();
        OrderWork orderWork = orderWorkService.findOrderWorkByKey(orderId, orderId);

        if (Objects.equals(GlobalConsts.SERV_CATEG_CLEAN, orderWork.getServCategId())) {
            // 清洗单，不需要同步
            return false;
        }

        // 啄木鸟收款额 = 师傅收款额 + 定金
        Integer zmnAmount = 0;

        Integer masterAmount = Optional.ofNullable(orderWork.getMasterAmount()).orElse(0);
        if (Objects.equals(GlobalConsts.PAY_STATUS_DONE, orderWork.getMasterPayStatus())) {
            zmnAmount += masterAmount;
        }
        Integer depositAmount = Optional.ofNullable(orderWork.getDepositAmount()).orElse(0);
        if (Objects.equals(GlobalConsts.PAY_STATUS_DONE, orderWork.getDepositStatus())) {
            zmnAmount += depositAmount;
        }

        if (zmnAmount <= 0) {
            // 没有师傅收款额，不需要同步
            return false;
        }

        BaseRsp result = DaoweiApiInvoker.pushMasterAmount(orderWorkLogChange.getExtOuterData(), orderWork,
                MoneyUtil.parseToYuan(zmnAmount));

        log.info("【到位】同步啄木鸟收款额：{}", JSON.toJSONString(orderWorkLogChange));

        _saveSyncResult(orderWorkLogChange, DaoweiConsts.SYNC_LOG_ORDER_DIFF, result);
        return true;
    }


    /**
     * 保存状态同步结果信息
     * @param orderWorkLogChange
     * @param syncLogCode
     * @param result
     */
    private void _saveSyncResult(OrderWorkLogChange orderWorkLogChange, int syncLogCode, BaseRsp result) {
        if (result == null) {
            return;
        }

        OrderNotifyLog orderNotifyLog = new OrderNotifyLog();
        orderNotifyLog.setMqMsgKey(orderWorkLogChange.getMqMsgKey());
        orderNotifyLog.setOrderId(orderWorkLogChange.getOrderId());
        orderNotifyLog.setChannelId(orderWorkLogChange.getChannelId());
        orderNotifyLog.setOrderStatus(orderWorkLogChange.getStatus());
        orderNotifyLog.setOrderResultStatus(orderWorkLogChange.getResultStatus());
        orderNotifyLog.setNotifyStatus(String.valueOf(syncLogCode));
        orderNotifyLog.setType(OrderConsts.ORDER_NOTIFY_TYPE_CHANGE);
        orderNotifyLog.setNotifyTime(DateUtil.getNow());
        orderNotifyLog.setNotifyResultMsg(
                String.format("[%s]-%s", DaoweiConsts.getSyncLogName(syncLogCode), result.getMsg()));

        ResultDTO resultDTO = new ResultDTO();
        resultDTO.setStatus("ok".equals(result.getStatus()) ? StatusConsts.STATUS_SUCCESS : StatusConsts.STATUS_ERROR);
        resultDTO.setData(orderNotifyLog);

        orderNotifyLogBService.saveNotifyLog(resultDTO);
    }
}
